import random
import time
import traceback

import pandas
import pyautogui
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import pyperclip
from src import EnvironmentVariables
from src.DataManager.ArticleManager import article_manager
import matplotlib.pyplot as plt
import numpy as np


class ChatGPTCrawler:
    def __init__(self):
        chrome_options = Options()
        chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222")
        self.driver = webdriver.Chrome(options=chrome_options)
        self.input_area = self.driver.find_element(By.TAG_NAME, "textarea")
        self.input_area.clear()

    def conversation(self, msg: str):
        self.input_area.clear()
        chat_num = len(self.driver.find_elements(By.XPATH,
                                                 "/html/body/div[1]/div[1]/div[1]/main/div[1]/div/div/div/div"))
        self.send_message(msg)
        self.driver.implicitly_wait(10)
        return self.get_ans(chat_num + 1)

    def send_message(self, msg: str):
        pyperclip.copy(msg)
        self.input_area.send_keys(Keys.CONTROL, "v")
        self.input_area.send_keys(Keys.ENTER)

    def get_ans(self, target: int):
        try:
            WebDriverWait(self.driver, 50).until(EC.visibility_of_element_located((By.XPATH,
                                                                                   "/html/body/div[1]/div[1]/div[1]/main/div[1]/div/div/div/div[%d]/div/div[2]/div[2]/div" % target)))
        finally:
            last_child = self.driver.find_element(By.XPATH,
                                                  "/html/body/div[1]/div[1]/div[1]/main/div[1]/div/div/div/div[%d]" % target)
            return last_child.text

    @staticmethod
    def refresh():
        global gpt_bot
        del gpt_bot
        pyautogui.keyDown("f5")
        time.sleep(5)
        gpt_bot = ChatGPTCrawler()


def make_ask_sentence(title, post_date, main_body) -> str:
    return f"""帮我看看这篇财经评论的情感是看多看空还是中性。
    题目:{title}
    发表日期:{post_date}
    正文:
    {main_body}
    """


def check_artificial_tag():
    excel_path = EnvironmentVariables.BASE_PATH + "data/artificially tagging.xlsx"
    with open(excel_path, "rb") as excel:
        tag_df = pandas.read_excel(excel, sheet_name=0)
    tag_df.set_index("article_id")
    tag_df["gpt"] = np.NaN
    ids = tag_df["article_id"]
    emotions = tag_df["emotion"]
    for i, article_id in enumerate(ids):
        time.sleep(random.randint(1,3))
        emotion = emotions[i]
        if emotion is not None:
            article_body = article_manager.get_data(clause="article_id=%d" % article_id,
                                                    column_name=["title", "post_date", "main_body"])
            if len(article_body) > 0:
                ask_sentence = make_ask_sentence(*article_body[0])
                ask_success = False
                res_data = None
                for retry_times in range(0, 5):
                    try:
                        res = gpt_bot.conversation(ask_sentence)
                        print(res)
                        res_data = parse_answer(res)
                        ask_success = True
                        break
                    except AssertionError as e:
                        print("需要手动重置")
                        raise e
                    except Exception as e:
                        print(traceback.format_exc())
                        ChatGPTCrawler.refresh()
                #if ask_success:
                    # emotion_dic = {"看多": '1', "中性": '0', "看空": '-1'}
                    #res_data = [str(_) for _ in res_data]
                    #res_data = {"emotion": emotion_dic[res_data[0]],
                    #            "positive": res_data[1],
                    #            "negative": res_data[2],
                    #            "neutral": res_data[3],
                    #            "article_id": article_id}
                    # article_manager.update(**res_data)
                    # tag_df.loc[article_id, "gpt"] = res_data["emotion"]
    # tag_df.to_excel(EnvironmentVariables.BASE_PATH + "gptTagging.xlsx")


def parse_answer(msg: str):
    # pattern = re.compile(
    # r"这篇财经评论的情感是[:：]? *(.*?)的?[;；] *看多概率[:：] *(\d*)% *[;；] *看空概率[:：] *(\d*)% *[;；] *中性概率[:：] *(\d*)%")
    # data = pattern.search(msg).groups()
    # assert len(data) == 4

    return []


def show_emotion_map(data):
    x = list(data.keys())
    x = [None if np.isnan(_) else _ for _ in x]
    while None in x:
        x.remove(None)
    y = [data.get(_) for _ in x]
    plt.figure()
    plt.bar(x, y)
    plt.figure()
    plt.pie(y, labels=[str(_) for _ in x], autopct="%0.2f%%")
    plt.show()


def main():
    check_artificial_tag()


if __name__ == '__main__':
    gpt_bot = ChatGPTCrawler()
    main()
